#include "mloop.h"

#define INTERVAL 50.0
#define ROUND_MAX 150000
#define CHECKPOINT 5000

void randomwalk(int max_output, float threshold)
{
	int i, n, num, flag1, flag2;
	int niter, norm, bin0, bin1, *H;
	double random_number;
	float *S, f, E_max, E_low, E_high, E_cut, converged;

	converged = -1.0;

	E_cut = 50.0 * loop.resnum;
	loop.circle = (2 * (loop.resnum - 1) > 10) ? 10 : 2 * (loop.resnum - 1);
	E_low = E_high = current[0].energy;

	flag2 = 0;

	for (niter = 1; niter <= 100; niter ++)
	{
		num = 0;

		for (n = 0; n < ROUND_MAX; n++)
		{
			memcpy (&current[1], &current[0], sizeof (struct candidate));

			random_number = drand48 ();
			if (random_number < loop.probility)
				purturb_mainchain ();
			else
				purturb_sidechain ();

			if (current[1].energy > E_high)
			{
				E_high = current[1].energy;
				if (E_high * 0.05 > 150.0 * loop.resnum)
					E_cut = 150.0 * loop.resnum;
				else if (50.0 * loop.resnum < E_high * 0.05)
					E_cut = E_high * 0.05;
			}
			else if (current[1].energy < E_low)
				E_low = current[1].energy;

			if ((niter > 1 || n >= 50000) && current[1].energy < E_low + E_cut && current[1].packing < 2)
			{
				num ++;
				memcpy (&candidate[nsaves], &current[1], sizeof (struct candidate));
				loop_cluster (threshold);
				if (num % CLUSTER_THRESHOLD == 0)
				{
					printf ("Samples: %d Nsaves: %d\n", num, nsaves);
					if (nsaves == nsaves2)
					{
						reinit (&current[0]);
						flag1 ++;
						if (flag1 == 3)
						{
							converged = threshold;
							if (nsaves >= max_output * 0.75)
							{
								flag2 = 1;
								break;
							}
							else if (threshold >= 0.1)
							{
								threshold -= 0.1;
								printf ("Threshold1 decreased to %f\n", threshold);
							}
							flag1 = 0;
						}
					}
					else
					{
						flag1 = 0;
					}
					nsaves2 = nsaves;
				}
				if (nsaves == max_output)
				{
					flag2 = 1;
					break;
				}
			}

			memcpy (&current[0], &current[1], sizeof (struct candidate));
		}
		printf ("Iterate: %d E_low: %f E_high: %f E_cut: %f Sampled: %d Num: %d Nsaves: %d\n", niter, E_low, E_high, E_cut, n, num, nsaves);

		if (flag2) break;
	}

	if (converged > 0)
		printf ("Converge to %.2f\tTotal %d conformations are saved\n", converged, nsaves);
}
